package models

import (
	"database/sql"
	"fmt"
	"log"
	"os"
	"time"

	_ "github.com/go-sql-driver/mysql"
	"gorm.io/driver/mysql"
	"gorm.io/driver/sqlite"
	"gorm.io/gorm"
	"gorm.io/gorm/logger"
)

var DB *gorm.DB

// SetupDB 初始化数据库连接
func SetupDB(dbType, mysqlDSN, sqlitePath string, logMode bool) (*gorm.DB, error) {
	var err error
	
	newLogger := logger.New(
		log.New(os.Stdout, "\r\n", log.LstdFlags), // io writer
		logger.Config{
			SlowThreshold:             time.Second, // 慢 SQL 阈值
			LogLevel:                  logger.Info, // 日志级别
			IgnoreRecordNotFoundError: true,        // 忽略记录未找到错误
			Colorful:                  true,        // 彩色打印
		},
	)

	if logMode {
		newLogger.LogMode(logger.Info)
	} else {
		newLogger.LogMode(logger.Error)
	}

	if dbType == "mysql" {
		// 首先尝试创建数据库（如果不存在）
		err = createDatabaseIfNotExists(mysqlDSN)
		if err != nil {
			return nil, fmt.Errorf("创建数据库失败: %v", err)
		}

		DB, err = gorm.Open(mysql.Open(mysqlDSN), &gorm.Config{
			Logger: newLogger,
		})
	} else {
		DB, err = gorm.Open(sqlite.Open(sqlitePath), &gorm.Config{
			Logger: newLogger,
		})
	}

	if err != nil {
		return nil, err
	}

	// 自动迁移数据表结构
	err = DB.AutoMigrate(&User{}, &Ticket{}, &Comment{})
	if err != nil {
		return nil, err
	}

	// 检查是否需要创建管理员账号
	var count int64
	DB.Model(&User{}).Count(&count)
	if count == 0 {
		// 创建默认管理员
		adminUser := User{
			Username: "admin",
			Password: "admin123", // 密码会在保存前自动哈希
			Email:    "admin@example.com",
			RealName: "系统管理员",
			Role:     RoleAdmin,
		}
		result := DB.Create(&adminUser)
		if result.Error != nil {
			fmt.Println("创建管理员账号失败:", result.Error)
		} else {
			fmt.Println("已创建默认管理员账号, 用户名: admin, 密码: admin123")
		}
	}

	return DB, nil
}

// 创建MySQL数据库（如果不存在）
func createDatabaseIfNotExists(dsn string) error {
	// 从DSN中提取数据库名
	dsnWithoutDB := extractDSNWithoutDB(dsn)
	dbName := extractDBName(dsn)
	
	if dbName == "" {
		return fmt.Errorf("无法从DSN中提取数据库名")
	}

	// 连接到MySQL（不指定数据库）
	db, err := sql.Open("mysql", dsnWithoutDB)
	if err != nil {
		return err
	}
	defer db.Close()

	// 创建数据库（如果不存在）
	query := fmt.Sprintf("CREATE DATABASE IF NOT EXISTS %s CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci", dbName)
	_, err = db.Exec(query)
	return err
}

// 从DSN中提取不包含数据库名的部分
func extractDSNWithoutDB(dsn string) string {
	// 假设DSN格式为：user:pass@tcp(host:port)/dbname?param=value
	// 需要转换为：user:pass@tcp(host:port)/
	
	for i := 0; i < len(dsn); i++ {
		if dsn[i] == '/' && i+1 < len(dsn) && dsn[i+1] != '/' {
			// 找到了数据库名开始的位置
			parts := dsn[i+1:]
			questionIdx := -1
			for j := 0; j < len(parts); j++ {
				if parts[j] == '?' {
					questionIdx = j
					break
				}
			}
			
			if questionIdx != -1 {
				// 如果有查询参数，保留它们
				return dsn[:i+1] + parts[questionIdx:]
			} else {
				// 如果没有查询参数，不添加斜杠
				return dsn[:i+1]
			}
		}
	}
	return dsn
}

// 从DSN中提取数据库名
func extractDBName(dsn string) string {
	// 假设DSN格式为：user:pass@tcp(host:port)/dbname?param=value
	
	dbStart := -1
	dbEnd := len(dsn)
	
	for i := 0; i < len(dsn); i++ {
		if dsn[i] == '/' && i+1 < len(dsn) && dsn[i+1] != '/' {
			// 找到了数据库名开始的位置
			dbStart = i + 1
			break
		}
	}
	
	if dbStart == -1 {
		return ""
	}
	
	// 查找数据库名的结束位置（如果有查询参数）
	for i := dbStart; i < len(dsn); i++ {
		if dsn[i] == '?' {
			dbEnd = i
			break
		}
	}
	
	return dsn[dbStart:dbEnd]
}

// GetDB 获取数据库连接
func GetDB() *gorm.DB {
	return DB
} 